package com.myApp.db;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.util.List;

import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

public class DatabaseHelper extends SQLiteOpenHelper  {
	
	private static final String DB_NAME = "setting.db";

	@Override
	public void onCreate(SQLiteDatabase arg0) {
	}

	@Override
	public void onUpgrade(SQLiteDatabase arg0, int arg1, int arg2) {
	}
	
	public DatabaseHelper(Context ct) {
		
		super(ct,DB_NAME,null,1); 
	}
	
	public boolean insert(String insert){

		this.getWritableDatabase().execSQL(insert);
		return true;
	}
	
	public boolean update(String update){
		
		this.getWritableDatabase().execSQL(update);
		return true;
	}
	
	public boolean delete(String del){
		
		this.getWritableDatabase().execSQL(del);
		return true;
	}
	
	/**
	 * 加载全部数据到容器
	 * @param <T> 数据行对象
	 * @param container 容器类对象
	 */
	public <T> boolean loadAll(List<T> container){
		
		ParameterizedType pt = (ParameterizedType) container.getClass().getGenericSuperclass();
		
		container.clear();
		
		Class<?> classOfRecord;
		
		Cursor cursor = null;
		
		try {
			
			// 获取数据行对象的类类型
			classOfRecord = (Class<?>)pt.getActualTypeArguments()[0];
			
			// 根据POJO对象的属性名拼接检索语句
			StringBuilder selectSql = new StringBuilder("select ");
			String tableName = convertObjectToDb(classOfRecord.getSimpleName());
			
			Field[] fields = classOfRecord.getDeclaredFields();
			
			for (int i = 0; i < fields.length; i++){
				
				selectSql.append(convertObjectToDb(fields[i].getName()));
				
				if (i == fields.length - 1){
					selectSql.append(" ");
				} else {
					selectSql.append(", ");
				}
			}
			
			selectSql.append("from ");
			selectSql.append(tableName);
			
			// 执行检索语句
			cursor = this.getReadableDatabase().rawQuery(selectSql.toString(), null);
			
			while (cursor.moveToNext()) {
				
				T objectOfRecord = (T) classOfRecord.newInstance();
				
				for (int i = 0; i < fields.length; i++){
					
					Method setter = classOfRecord.getMethod(getSetterByFieldName(fields[i].getName()), fields[i].getType());
					
					Class<?> setterType = setter.getParameterTypes()[0];
					
					Method[] gettersOfCursor = cursor.getClass().getMethods();
					
					Object arg = null;
					
					// 匹配Cursor对象的Getter返回值类型和数据行对象的Setter参数类型
					// 以便取得检索结果的对应值
					for (Method getterOfCursor : gettersOfCursor){
						
						if (getterOfCursor.getReturnType().getName().equals(setterType.getName()) && 
							getterOfCursor.getName().replaceAll("get", "").toLowerCase().equals(setterType.getSimpleName().toLowerCase())){
							
							arg = getterOfCursor.invoke(cursor, i);
						}
					}
					
					if (arg == null){
						throw new IllegalArgumentException("type " + setterType.getName() + " mismatch");
					}
					
					setter.invoke(objectOfRecord, arg);
				}
				
				// 把每一行数据对应的数据行对象放入容器类对象
				container.add(objectOfRecord);
			}
			
		} catch (NoSuchMethodException e) {
			// 没有找到Setter
			e.printStackTrace();
			
			return false;
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
			
			return false;
		} catch (IllegalAccessException e) {
			e.printStackTrace();
			
			return false;
		} catch (InvocationTargetException e) {
			e.printStackTrace();
			
			return false;
		} catch (InstantiationException e) {
			e.printStackTrace();
			
			return false;
		} finally{
			
			if (cursor != null)
			cursor.close();
		}
		
		return true;
	}
	
	/**
	 * 类字段向DB字段转换
	 * 头文字小写并添加下划线
	 * 
	 * @param object 类字段
	 */
	private String convertObjectToDb(String object){
		
		String db = "";
		
		char[] characters = object.toCharArray();
		
		for (int i = 0; i < characters.length; i++){
			
			if (Character.isUpperCase(characters[i])){
				
				if (i == 0){
					db += Character.toLowerCase(characters[i]);
				} else {
					db += "_" + Character.toLowerCase(characters[i]);
				}
				
			}else{
				
				db += characters[i];
			}
		}
		
		return db;
	}
	
	/**
	 * 根据属性名取setter方法名
	 * 
	 * @param fieldName 属性名
	 */
	private String getSetterByFieldName(String fieldName){
		
		String setter = "set";
		
		String firstChar = fieldName.substring(0, 1);
		
		setter += firstChar.toUpperCase();
		
		setter += fieldName.substring(1);
		
		return setter;
	}

}
